# 获取值
function get_cmt_value(s){
    file="YML_VAR.sh" NR
    cmd="sh " file
    rmcmd="rm " file
    printf("YML_VAR=%s\n", s)     > file
    printf("echo \"$YML_VAR\"\n") >> file
    cmd | getline YML_VAR
    system(rmcmd)
    return YML_VAR
}
function get_abs_key(keys, root, sk){
    idx = root - root/2
    if (root == 0) {
        delete keys
    } else {
        len = length(keys)
        for(i=0;i<len;i++){
            if (i > idx) {
                delete keys[idx+1]
            }
        }
    }
    keys[idx] = sk
    len = length(keys)
    p=""
    for(i=0;i<len;i++){
        p = i == 0 ? keys[i] : p "." keys[i]
    }
    return p
}
function ltrim(s){
    sub(/[[:blank:]]*/, "", s)
    return s
}
function is_array_open(s){
    return (s ~ /^[[:blank:]]*-/)
}
function get_key(s){
    # Get key
    #   kind: 'console123      #' #abc
    idx = index(s, ": ")
    if (idx > 0) {
        sk=substr(s, 0, idx-1)
    } else {
        #   requests:
        if ($0 ~ /:$/) {
            # 当前行无值
            idx = length(s)
            sk=substr(s, 0, idx-1)
        } else {
            # 只有值，比如数组元素
            sk = s
        }
    }
    return ltrim(sk)
}
function get_value(s){
    # 内行存在注释
    return (index(s, "#") > 0 ? get_cmt_value(s) : s)
}
function is_append(command){
    return (command == "append")
}
function is_insert(command){
    return (command == "insert")
}
function is_set(command){
    return (command == "set")
}
function is_get(command){
    return (command == "get")
}
function is_remove(command){
    return (command == "remove")
}
function is_list(command){
    return (command == "list")
}
function is_output(command){
    return (is_append(command) || is_set(command) || is_insert(command) || is_remove(command))
}
function trim_start_key(key, from){
    sub("^[[:blank:]]*"key":?[[:blank:]]*", "", from)
    return from
}
# raw: $0
# sp: string position
# sv: string value
# new_value: string new value
function replace_value(raw, sp, sv, new_value){
    old=substr(raw, 0, sp) "" sv
    new=substr(raw, 0, sp) "" new_value
    # print "old: " old
    # print "new: " new
    old_raw=raw
    sub(old, new, raw)
    if (raw == old_raw) {
        # 没有匹配单引号或双引号
        left = substr(raw, sp + 1, 1)
        right = substr(raw, sp + 1 + length(sv) + 1, 1)
        old=substr(raw, 0, sp) "" left "" sv "" right
        new=substr(raw, 0, sp) "" left "" new_value"" right
        sub(old, new, raw)
    }
    return raw
}

BEGIN{
    is_arr=0
    if (is_set(command)) {
        # set 
        if (input_file != "") {
            # props file
            while((getline var < input_file)==1) {
                idx0 = index(var, "=")
                prop0=substr(var, 0, idx0-1)
                value0=substr(var, idx0+1, length(var))
                setup_props[prop0] = value0 == "" ? " " : value0 
            }
        }
    } else if(is_insert(command)){
        if (input_file != "" && (matcher == "" || insert_line==0)) system(sprintf("cat %s", input_file))
    }
}
$0 ~ /^[[:blank:]]*#/ || NF == 0 {
    if(is_output(command)) print $0
    next
}
{
    if(is_insert(command)){
        if (insert_line == NR) system(sprintf("cat %s", input_file))
        print $0
        next
    }
    raw=$0

    # 数组打开
    if (is_array_open($0)) {
        is_arr = 1
        pos += 1
        space_count=index($0, "- ") + 1
    } else {
        # 数组关闭
        if(index($0, $1) - 1 != space_count){
            is_arr = 0
            pos = -1
        }
    }

    if (is_arr == 1) {
        sub(/[[:blank:]]*- /, "", $0)
        pretty_key = abs_key "[" pos "]"
        if ($1 ~ /:[[:blank:]]*$/) {
            # 对象
            sk = get_key($0)
            sv0 = trim_start_key(sk, $0)
            sp=length(raw)-length(sv0)
            sv = get_value(sv0)
            pretty_key = pretty_key "." sk
        } else {
            # 数组
            sv = get_value($0)
            sk = ""
            sp=0
        }

        if(is_list(command)) {
            if (matcher != "") {
                if (matcher == pretty_key) print NR
            } else {
                print "#" NR "  " pretty_key
            }
            next
        }

        if(is_set(command) && matcher == "") {
            new_value = setup_props[pretty_key]
        }
        
        # print "pretty_key:"pretty_key
        # print "matcher:"matcher
        # 全匹配
        if (pretty_key == matcher || setup_props[pretty_key] != ""){
            if(is_set(command)) {
                if(is_output(command)) print replace_value(raw, sp, sv, new_value)
            } else if(is_get(command)) {
                # 获取数值
                print sv
                next
            } else if(is_list(command)) {
                if (matcher != "") {
                    if (matcher == pretty_key) print NR
                } else {
                    print "#" NR "  " pretty_key
                }
                next
            }
        } else {
            if(is_output(command)) print raw
        }
        # print "#" NR ", abs_key=" abs_key "[" pos "]"", sk=" sk ", value=`"sv"`"
    } else {
        sk = get_key($0)
        # 空格结束索引
        root = index($0, $1) - 1
        abs_key = get_abs_key(keys, root, sk)
        pretty_key=abs_key
        sv0 = trim_start_key(sk, $0)
        sp=length(raw)-length(sv0)
        sv = get_value(sv0)

        if(is_list(command)) {
            # print "pretty_key:"pretty_key
            # print "matcher:"matcher
            if (matcher != "") {
                if (matcher == pretty_key) print NR
            } else {
                print "#" NR "  " pretty_key
            }
            next
        }

        if(is_set(command) && matcher == "") {
            new_value = setup_props[pretty_key]
        }

        # 全匹配
        # print "pretty_key:"pretty_key
        # print "matcher:"matcher
        if (pretty_key == matcher || setup_props[pretty_key]){
            if(is_set(command)) {
                if(is_output(command)) print replace_value(raw, sp, sv, new_value)
            } else if(is_get(command)) {
                # 获取数值
                print sv
                next
            }
        } else {
            if(is_output(command)) print raw
        }

        # print "#" NR ", abs_key=" abs_key ", sk=" sk ", value=`"sv"`"
    }
}
END {
    if(is_append(command)) {
        # print "input_file: " input_file
        if (input_file != "") system(sprintf("cat %s", input_file))
    }
}